# coding=utf-8
# 第一版 2022/3/21 author: ylong52@21cn.com
# 元节数 artmeta.cn/pages/home/index
from asyncore import loop
from http import server
from lib2to3.pgen2 import driver
from urllib.parse import urlparse
from myselenium import *
import sys
from LocalStorage import *
from browsermobproxy import Server
from weblogin import * 
import json

class artMain:
    #解决占用端口
    def kill_process(self,port):
        # os.system('taskkill /im chromedriver.exe /F')
        # os.system('taskkill /im chrome.exe /F')

        ret = os.popen("netstat -nao|findstr '"+str(port)+"'")    
        #注意解码方式和cmd要相同，即为"gbk"，否则输出乱码
        str_list = ret.read() 
        time.sleep(getRandomNumberByRange(1,5))  
        ret_list = re.split('',str_list)
        try:
            process_pid = list(ret_list[0].split())[-1]
            os.popen('taskkill /pid ' + str(process_pid) + ' /F')
            print("端口已被释放")
        except:
            #print("端口未被使用")
            return True

    #读ini文件  
    def getGoodINIUrl(self):
        cfg1 = "./config.ini"
        config = configparser.ConfigParser()
        config.read(cfg1, encoding="utf-8-sig")
        self.config = config

        # cfg2 = config.get("setup", "loginfile")
        # conf2 = configparser.ConfigParser()
        # conf2.read(cfg2, encoding="utf-8-sig")
        # self.logconfig = conf2

    def startMenu(self): 
        print("***菜单******************************************\n")
        print("*1,登录[输入手机号和短码]")      
        print("*2,扫[数字藏品市场]所有商品的价格显示低于指定价格")        
        print("*3,扫[数字藏品市场]指定系列商品的价格显示低于指定价格")    
        print("*0,退出")
        print("注：以上的配置修改config.ini文件")
        print("*************************************************")
        menuList = ['0','1','2','3','4']
        inputmenu = input("菜单输入:")        
        if (inputmenu=='0'):
            os._exit(0) 
       
        self.getGoodINIUrl()     
        self.hasDriverStart = 0;  #防止driver多次加载
        if (inputmenu in menuList):
            if (inputmenu=='1'):                
                ret = weblogin().main()
                if (ret==True):
                    self.startMenu()
                return 

            if (inputmenu=='2'):  
                while True:
                    if self.hasDriverStart == 0:
                        self.startProxy() 
                    self.scan_home()
                return

            if (inputmenu=='3'):
                while True:
                    if self.hasDriverStart == 0:
                        self.startProxy() 
                    self.scan_onlyGroupId()
                return
 

    #主程序
    def __init__(self): 
        now = time.strftime("%Y-%m-%d-%H")
        self.logfile = './logs/logs'+format(now)+'.txt'; 
        self.startMenu() 
           
    def startProxy(self):
       
        if self.hasDriverStart==0:
            dict={'port':8090} #browsermob-proxy端口
            self.kill_process(8090);
            try:
                sserver = Server(r".\browsermob-proxy-2.1.4\bin\browsermob-proxy.bat",options=dict)                
                sserver.start()
            except:
                self.kill_process(8090);
                sserver.start()

            self.proxy = sserver.create_proxy()                            
            self.aDriver()        
            
            self.checkLoginStart()
            self.hasDriverStart = 1
            

         

  
    def aDriver(self):

        cfg1 = "./config.ini"
        conf = configparser.ConfigParser()
        conf.read(cfg1, encoding="utf-8-sig")

        chrome_options2 = Options()
        if ("1" != conf.get("setup", "viewgoogle")):
            chrome_options2.add_argument('--headless') #无头浏览器

        chrome_options2.add_argument('--disable-gpu')
        chrome_options2.add_argument('--ignore-certificate-errors')
        chrome_options2.add_argument('--ignore-ssl-errors')
        chrome_options2.add_argument('--proxy-server={0}'.format(self.proxy.proxy))
        # chrome_options2.add_argument("--auto-open-devtools-for-tabs")
        chrome_options2.add_argument("--enable-web-app-frame")
        chrome_options2.add_argument("--disable-extensions")
        chrome_options2.add_argument("--enable-mobile-emulation")
        prefs = {"profile.managed_default_content_settings.images": 2}
        chrome_options2.add_experimental_option("prefs", prefs)
        #手机模式
        # WIDTH = 600
        # HEIGHT = 1452
        # PIXEL_RATIO =2.0
        # # UA 必须要是手机设备的
        # UA = 'Mozilla/5.0 (Linux; Android 4.1.1; GT-N7100 Build/JRO03C) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/35.0.1916.138 Mobile Safari/537.36 T7/6.3'
        # mobileEmulation = {"deviceMetrics": {"width": WIDTH, "height": HEIGHT, "pixelRatio": PIXEL_RATIO}, "userAgent": UA}
        # # chrome_options2.add_experimental_option("mobileEmulation", mobileEmulation)        
        # chrome_options2.add_experimental_option('mobileEmulation', mobileEmulation)   
        # mobileEmulation = {"deviceName": "iPad Air"}
        # chrome_options2.add_experimental_option("mobileEmulation", mobileEmulation)        

        # driver = webdriver.Chrome(options=chrome_options2)
        # chrome_options2 = DebugBrowser().debug_chrome(proxy);  #只启动一个google调试
        self.driver=webdriver.Chrome(options=chrome_options2)
        self.driver.set_window_size(600,800)
        self.driver.get('https://artmeta.cn/pages/home/index')      
       

 


    #检查登录
    def checkLoginStart(self):  
        cfg1 = "./config.ini"
        config = configparser.ConfigParser()
        config.read(cfg1, encoding="utf-8-sig")
        self.config = config

        cfg2 = config.get("setup", "loginfile")        
        conf2 = configparser.ConfigParser()
        conf2.read(cfg2, encoding="utf-8-sig")
        self.logconfig = conf2

        storage = LocalStorage(self.driver)
        _setion = "login";
        storage["truename"] = self.logconfig.get(_setion, "truename")
        storage["UserLoginToken"] = self.logconfig.get(_setion, "UserLoginToken")
        storage["userinfo"] =  self.logconfig.get(_setion, "userinfo")       
        print('登录中......')
        self.driver.get('https://artmeta.cn/pages/usercenter/usercenter')        
        
        time.sleep(getRandomNumberByRange(1,5))  
        if(storage.get("truename")==None):
            print('帐号登录登录失败!!!!!')             
            self.driver.quit()
            sys.exit()

        else:
            print(f'{storage["truename"]} ,帐号登录成功 >>>')
            return True   


    #找到 
    def scan_home(self):
        url = 'https://artmeta.cn/pages/home/index'     
        self.proxy.new_har("huaruntong", options={'captureHeaders': True, 'captureContent': True})
        self.driver.get(url)
        time.sleep(getRandomNumberByRange(1,5))  

        element = self.driver.find_element(By.TAG_NAME,'body')
        element.send_keys(Keys.CONTROL,Keys.SHIFT,'m')  

        time.sleep(getRandomNumberByRange(1,5))  
        _xpathstr = "//uni-view/uni-view[4]/uni-view/uni-view[1]/uni-view/uni-view/uni-view/uni-view[3]"
        self.driver.find_element(By.XPATH,_xpathstr).click()
        time.sleep(getRandomNumberByRange(1,5))  
        _hasxpathStr = "//uni-view[@class='btn-tabs bg-white']/uni-view[@class='btn-tabs-item text-color-77 active']"
        hasxpath = self.driver.find_element(By.XPATH,_hasxpathStr)
        
        if (hasxpath == False):     
            print("_xpath hasxpath false")
            raise SelfExceptionError("点击数字藏品市场按钮出现")            
            os._exit(0)
        else:                    
             
            self.worksdetail_dict = {}     
            self.__getGroupIdHarUrl(self.proxy.har)    #数藏是先分组
 
            with open(self.logfile,'a',encoding="utf-8") as file:
                   file.write("\n=====数字藏品市场=========\n")
            

            for k,v in self.worksdetail_dict.items():
                with open(self.logfile,'a',encoding="utf-8") as file:
                   file.write("\n"+'GroupId_Url:'+v+"\n")
                self.derivativedetail(v);
                
        time.sleep(2)         
        print('line: 223, 完成扫货  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n')
       

    #取包
    def __getGroupIdHarUrl(self,result): 
         
        for entry in result['log']['entries']:
            _url = entry['request']['url']
            if "https://api.artmeta.cn/api.ashx" in _url:
                # print(">>>>>>>>>>"+_url+">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
                _response = entry['response']
                _content = _response['content']
                if "GroupId" in json.dumps(_content):                   
                    self.__hardataout(_content)
                    break;
                   
                # print("<<<< url end <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n")
        # print("<<<< url end <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<")

    
    ##分析接口数据
    def __hardataout(self,data):
        
        #json.dumps将python对象格式化成json字符（将dict转化成str）
        #json.loads将json字符串解码成python对象（将str转化成dict）
        _dict = json.loads(data['text'])
        _datalist = _dict['Data']['Data']   #datalist是dict类型
        # print("Line: 185, 找到 GroupId 页面\n\n")
        # print(">>>>>>>>>>_dict>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n")
        # print(_dict)
        # print("<<<<<<<<_dict<<<<< \n\n")
        # os.system('pause')

        for i in _datalist:                       
            # print(i['Data'].get('GroupId'))
            # print(i)
            try:
                _obj = i['Data']
            except:
                _obj = i 

            try:
                astr = "系列： GroupId:"+str(_obj['GroupId'])+",GroupName:"+str(_obj['GroupName'])
                print(astr)
                if (to_int(_obj['GroupId'])>0):
                    _id = str(_obj['GroupId']);                       
                    self.worksdetail_dict[_id] = "https://artmeta.cn/pages/derivativedetail/derivativedetail?id="+_id+'&name='+str(_obj['GroupName'])   #可以去复
                # print(" ----  \n")
            except:
                loop 
       
 
        
    #找到转售市场
    def derivativedetail(self,_url):
        # print(f'Line 203,打开{_url}>>>>>>')
        self.proxy.new_har("huaruntong2", options={'captureHeaders': True, 'captureContent': True})
        self.driver.get(_url)
        time.sleep(getRandomNumberByRange(1,5))  
        _xpathstr = '//*[@id="u-tab-item-1"]'
        self.driver.find_element(By.XPATH,_xpathstr).click()
        time.sleep(getRandomNumberByRange(1,5))   #3S 时间不能去
        result = self.driver.find_element(By.CLASS_NAME, 'list')
        if (result == False):
            raise SelfExceptionError("未找到转到市场的按钮")
 
        for i in range(4):
            # print(f'第{i+1}页>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n')
            item_id2 = self.__derivativeHarUrl2(self.proxy.har)
            
            #mouse滚轮向下翻页  
            js="window.scrollTo(0,document.body.scrollHeight)"
            self.driver.execute_script(js)
            # print(f'共输出条:{self.countList}记录')              
            time.sleep(getRandomNumberByRange(1,5))   #时间不能去提


    #取包
    def __derivativeHarUrl2(self,result):
        
        for entry in result['log']['entries']:
            _url = entry['request']['url']
            if "https://api.artmeta.cn/api.ashx" in _url:
                # print("line 241, >>>>>>>>>>"+_url+">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>")
                _response = entry['response']
                _content = _response['content']
                # print("line 244, _content>>>>>>>>>>>>>>>>>\n\n")
                if "GoodsId" in json.dumps(_content):
                    self.__dataout2(_content)
                

    
    ##分析接口数据
    def __dataout2(self,data):
        my_price = self.config.get("goods","price")  #最低的价格
        my_price = to_int(my_price)
        # print("_filter_price = ")
        # print(_filter_price)
        #json.dumps将python对象格式化成json字符（将dict转化成str）
        #json.loads将json字符串解码成python对象（将str转化成dict）
        _dict = json.loads(data['text'])
        try:
            _datalist = _dict['Data']['Data'] #datalist是dict类型 
        except:
            try:
                _datalist = _dict['Data']
            except:
                print("Line:340,有错误")
                print(_datalist)


        _find_num = 0
        _countList = 0
        for i in _datalist: 
            try:           
                astr= " id:"+str(i['GoodsId'])+",name:"+i['GoodsName']+",price:"+str(i['GoodsPrice'])
                if (my_price>0):
                    astr +=',我的出价:'+str(my_price)
                astr2 = astr    
                if (to_int(i['LockEndTimestamp'])>0):
                    astr2 += "Line:340 "+astr2+",被加锁..";

                print(astr2)

                with open(self.logfile,'a',encoding="utf-8") as file:
                        file.write("Line:340 "+astr+"\n")

                if (my_price>0 and my_price >= to_int(i['GoodsPrice']) and to_int(i['LockEndTimestamp'])==0 ):  
                        astr = '********** ,符合条件:'+astr
                        print(astr)                                        
                        _find_num +=1                   
                        if ('contion_find' == self._buynow(i['GoodsId'])):
                            #_buynow
                            loop;  
                        else:
                            #等买入
                            break
                    

                # if (self.inputmenuType=="scan_all_sc"):  # 扫所有商品的当前价格
                #     _countList= _countList + 1
                #     # astr = "No."+str(_countList)+",id:"+str(i['GoodsId'])+",name:"+i['GoodsName']+",price:"+str(i['GoodsPrice'])
                #     # print(astr)                
                #     with open(self.logfile,'a',encoding="utf-8") as file:
                #         file.write(astr+"\n")
            except:
                loop

        # print("\n\n")
        # self.countList = _countList
        # if (_find_num==0 and my_price>0):
        #     astr = "未找到符合条件的商品ID"+"https://artmeta.cn/pages/worksdetail/worksdetail?id="+str(i['GoodsId'])
        #     with open(self.logfile,'a',encoding="utf-8") as file:
        #         file.write(astr+"\n") 
        #     print(astr)
        # return False    
    
    #购买页面
    def _buynow(self,item_id):
    
        url = "https://artmeta.cn/pages/worksdetail/worksdetail?id="+str(item_id)
        self.driver.get(url)
        try:
            element = WebDriverWait(self.driver,1,0.1).until(           
                EC.presence_of_element_located((By.CLASS_NAME, "works-offer-purchase"))
            )
            element.click()
        except:
            return 'contion_find' 

        try:
            _hasxpathStr = '//*[@id="offer"]/uni-view/uni-view/uni-view'
            hasxpath = self.driver.find_element(By.XPATH,_hasxpathStr)     #/存在'锁单'
            if (hasxpath):           
                return 'contion_find' 
        except:
            pass


        # element = WebDriverWait(self.driver,3,0.1).until(
        #     ////uni-scroll-view/div/div/div/uni-view/uni-view[3]  //确认下单

        #     EC.presence_of_element_located((By.CLASS_NAME, "works-offer-purchase"))  #购买
        # )        
        # element.click()

        try:
            element2 = self.driver.find_element(By.CLASS_NAME,'u-model__content__message')
            if (element2):
                print("已存在待支付的订单")
                os.system("pause")    #任一键
                self.aMenu() 
        except: 
            pass

        time.sleep(getRandomNumberByRange(1,5))  

        _xpathstr ='//uni-scroll-view/div/div/div/uni-view/uni-view[3]'  #确认下单
        aElement = wait_for_elem_xpath_func(browser=self.driver,by_value = _xpathstr)
        if (aElement!=None):
            aElement.click()
        else:
            _errorMsg = "line:419,Error url:"+url
            print(_errorMsg)
            with open(self.logfile,'a',encoding="utf-8") as file:
                file.write("\n"+_errorMsg)
            return 'contion_find' 
            os.system("pause")    #任一键 
            self.aMenu() 


        aElement = wait_for_elem_xpath_func(browser=self.driver,vByType='class_name',by_value = 'pay')   #点支付宝
        if (aElement!=None):
            aElement.click()
        else:
            print("line:419,Error：支付失败")
            os.system("pause")    #任一键 
            self.aMenu() 

        print("\n\n￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣")
        print("已经点了立即支付，请去个人中心付款\n")
        print(f'当前时间:'+time.strftime("%Y-%m-%d %H:%M:%S"))
        print("⊙▽⊙ ⊙▽⊙ ⊙▽⊙ \n\n")
        os.system("pause")    #任一键

        # # os.system("cls")
        # # print("\b")
        # if "worksdetail" in self.driver.current_url:
        #     print("\n\n￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣")
        #     print("支付失败！！！！！！,估计是账户被锁12小时。手工去查看个人中心 !!!!!\n\n")
        #     print(f'当前时间:'+time.strftime("%Y-%m-%d %H:%M:%S"))
        #     os.system("pause")    #任一键

        # if "支付宝" in self.driver.title:
        #     print("\n\n￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣￣▽￣")
        #     print("已经点了立即支付，请去个人中心付款\n")
        #     print(f'当前时间:'+time.strftime("%Y-%m-%d %H:%M:%S"))
        #     print("⊙▽⊙ ⊙▽⊙ ⊙▽⊙ \n\n")
        #     os.system("pause")    #任一键

        self.aMenu() 
            
 
    def scan_onlyGroupId(self):
        _url = "https://artmeta.cn/pages/derivativedetail/derivativedetail?id="+self.config.get("goods","group-id")
        self.derivativedetail(_url);        
        print('line: 474, 完成扫货  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<\n')
        time.sleep(getRandomNumberByRange(1,5))  







#-------------------- start 
if __name__ == '__main__':
    artMain()
 


